package chatclient.netio;




import chatclient.tools.ChatException;
import java.io.*;
import java.util.Date;

public abstract class Attr {

    abstract String[] getNames();

    abstract int getType();

    public Attr() {
        this((byte) 0);
    }

    public Attr(byte byte0) {
        id = byte0;
        value = new byte[0];
    }

    public Attr(byte byte0, byte abyte0[]) {
        this(byte0, abyte0, 0, abyte0.length);
    }

    public Attr(byte byte0, byte byte1)
            throws ChatException {
        this(byte0);
        setValue(byte1);
    }

    public Attr(byte byte0, int i)
            throws ChatException {
        this(byte0);
        setValue(i);
    }

    public Attr(byte byte0, String s)
            throws ChatException {
        this(byte0);
        setValue(s);
    }

    public byte getId() {
        return id;
    }

    public byte[] getValue() {
        if (offset != 0 || length != value.length) {
            byte abyte0[] = new byte[length];
            System.arraycopy(value, offset, abyte0, 0, length);
            value = abyte0;
            offset = 0;
        }
        return value;
    }

    public byte getByte() {
        return value[offset];
    }

    public int getInt()
            throws ChatException {
        if (intValue == null) {
            try {
                intValue = new Integer((new DataInputStream(new ByteArrayInputStream(value, offset, length))).readInt());
            } catch (IOException ioexception) {
                throw new ChatException(ioexception.toString());
            }
        }
        return intValue.intValue();
    }

    public String getString()
            throws ChatException {
        if (strValue == null) {
            try {
                strValue = (new DataInputStream(new ByteArrayInputStream(value, offset, length))).readUTF();
            } catch (IOException ioexception) {
                throw new ChatException(ioexception.toString());
            }
        }
        return strValue;
    }

    private String getIntAsString()
            throws ChatException {
        return Integer.toString(getInt());
    }

    private String getIPAsString()
            throws ChatException {
        StringBuilder stringbuffer = new StringBuilder();
        byte abyte0[] = getValue();
        stringbuffer.append(abyte0[0] & 0xff);
        stringbuffer.append('.');
        stringbuffer.append(abyte0[1] & 0xff);
        stringbuffer.append('.');
        stringbuffer.append(abyte0[2] & 0xff);
        stringbuffer.append('.');
        stringbuffer.append(abyte0[3] & 0xff);
        return stringbuffer.toString();
    }

    private String getSecsAsString()
            throws ChatException {
        StringBuilder stringbuffer = new StringBuilder();
        int i = getInt();
        int j = i / 3600;
        int k = (i % 3600) / 60;
        int l = i % 60;
        stringbuffer.append(j);
        stringbuffer.append(':');
        stringbuffer.append((char) (48 + k / 10));
        stringbuffer.append((char) (48 + k % 10));
        stringbuffer.append(':');
        stringbuffer.append((char) (48 + l / 10));
        stringbuffer.append((char) (48 + l % 10));
        return stringbuffer.toString();
    }

    private String getTimeAsString()
            throws ChatException {
        StringBuilder stringbuffer = new StringBuilder();
        Date date = new Date(1000L * ((long) getInt() & 0xffffffffL));
        int i = date.getHours();
        int j = date.getMinutes();
        int k = date.getSeconds();
        stringbuffer.append("[");        
        stringbuffer.append(date.getDate());
        stringbuffer.append('/');
        stringbuffer.append(date.getMonth() + 1);
        stringbuffer.append('/');
        stringbuffer.append(date.getYear() + 1900);        
        stringbuffer.append("] - [");
        stringbuffer.append(i);
        stringbuffer.append(':');
        stringbuffer.append((char) (48 + j / 10));
        stringbuffer.append((char) (48 + j % 10));
        stringbuffer.append(':');
        stringbuffer.append((char) (48 + k / 10));
        stringbuffer.append((char) (48 + k % 10));
        stringbuffer.append("]");           
        return stringbuffer.toString();
    }

    private String getBytesAsString() {
        StringBuilder stringbuffer = new StringBuilder();
        byte abyte0[] = getValue();
        stringbuffer.append('[');
        for (int i = 0; i < length; i++) {
            stringbuffer.append(hex[abyte0[offset + i] >> 4 & 0xf]);
            stringbuffer.append(hex[abyte0[offset + i] & 0xf]);
        }

        stringbuffer.append(']');
        return stringbuffer.toString();
    }

    public String getAsString() {
        try {
            switch (getType()) {
                case 3:
                    return getIPAsString();
                case 2:
                    return getIntAsString();
                case 4:
                    return getSecsAsString();
                case 5:
                    return getTimeAsString();
                case 1:
                    return getString();
            }
            return "";
        } catch (ChatException chatexception) {
        }
        return "";
    }

    public String quoteString(String s) {
        StringBuilder stringbuffer = new StringBuilder();
        stringbuffer.append('"');
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isISOControl(c) || "\"\\".indexOf(c) != -1) {
                stringbuffer.append("\\x");
                stringbuffer.append(hex[c >> 4 & 0xf]);
                stringbuffer.append(hex[c & 0xf]);
            } else {
                stringbuffer.append(c);
            }
        }

        stringbuffer.append('"');
        return stringbuffer.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof Attr) || ((Attr) obj).length != length) {
            return false;
        }
        for (int i = 0; i < length; i++) {
            if (((Attr) obj).value[((Attr) obj).offset + i] != value[offset + i]) {
                return false;
            }
        }

        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 47 * hash + this.id;
        return hash;
    }

    @Override
    public abstract Object clone();

    public Object clone(byte byte0, byte abyte0[], int i, int j) {
        Attr attr = (Attr) clone();
        attr.setValue(byte0, abyte0, i, j);
        return attr;
    }

    public void read(Reader reader)
            throws ChatException, IOException {
        char c;
        do {
            c = (char) reader.read();
            if (c == '\n') {
                throw new ChatException("no attribute name");
            }
        } while (Character.isWhitespace(c));
        String s = new String();
        s = (new StringBuilder(String.valueOf(s))).append(c).toString();
        do {
            reader.mark(1);
            c = (char) reader.read();
            if (!Character.isLetterOrDigit(c) && c != '_') {
                break;
            }
            s = (new StringBuilder(String.valueOf(s))).append(c).toString();
        } while (true);
        reader.reset();
        String as[] = getNames();
        for (id = 0; (id & 0xff) < as.length && !as[id & 0xff].equalsIgnoreCase(s); id++) {}
        if ((id & 0xff) == as.length) {
            try {
                id = (byte) Integer.parseInt(s);
            } catch (Exception exception) {
                throw new ChatException("unknown attribute name");
            }
        }
        do {
            reader.mark(1);
            c = (char) reader.read();
            if (c == '\n') {
                throw new ChatException("no attribute name");
            }
        } while (Character.isWhitespace(c));
        if ("-0123456789".indexOf(c) >= 0) {
            String s1 = new String();
            do {
                s1 = (new StringBuilder(String.valueOf(s1))).append(c).toString();
                reader.mark(1);
                c = (char) reader.read();
            } while ("x#0123456789abcdefABCDEF".indexOf(c) >= 0);
            reader.reset();
            setValue(Integer.decode(s1).intValue());
        } else if (c == '"') {
            String s2 = new String();
            do {
                c = (char) reader.read();
                if (c == '\n') {
                    throw new ChatException("no newline permitted in string");
                }
                if (c == '"') {
                    break;
                }
                s2 = (new StringBuilder(String.valueOf(s2))).append(c).toString();
            } while (true);
            setValue(s2);
        } else if (c == '[') {
            ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
            boolean flag = true;
            byte byte0 = 0;
            do {
                char c1 = (char) reader.read();
                if (c1 == '\n') {
                    throw new ChatException("no newline permitted in byte value");
                }
                if (c1 == ']' && flag) {
                    break;
                }
                byte byte1;
                if ((byte1 = (byte) "0123456789ABCDEF".indexOf(Character.toUpperCase(c1))) >= 0) {
                    byte0 |= byte1;
                    if (flag) {
                        byte0 <<= 4;
                    } else {
                        bytearrayoutputstream.write(byte0);
                        byte0 = 0;
                    }
                    flag = !flag;
                } else {
                    throw new ChatException((new StringBuilder("invalid character '")).append(c1).append("' in byte value").toString());
                }
            } while (true);
            byte abyte0[] = bytearrayoutputstream.toByteArray();
            setValue(abyte0, 0, abyte0.length);
        } else {
            throw new ChatException("invalid parameter value");
        }
    }

    @Override
    public String toString() {
        String as[] = getNames();
        StringBuilder stringbuffer = new StringBuilder((id & 0xff) >= as.length ? (new StringBuilder(String.valueOf(id & 0xff))).toString() : as[id & 0xff]);
        stringbuffer.append(' ');
        try {
            switch (getType()) {
                default:
                    throw new ChatException();

                case 1:
                    stringbuffer.append(quoteString(getString()));
                    break;

                case 0:
                case 2:
                case 3:
                case 4:
                case 5:
                    String s = getAsString();
                    if (s == null) {
                        throw new ChatException();
                    }
                    stringbuffer.append(s);
                    break;

                case 6:
                    stringbuffer.append((new StringBuilder(String.valueOf('{'))).append((new Command(new ByteArrayInputStream(getValue()))).toString()).append('}').toString());
                    break;

                case 7:
                    stringbuffer.append((new StringBuilder(String.valueOf('{'))).append((new Event(new ByteArrayInputStream(getValue()))).toString()).append('}').toString());
                    break;
            }
        } catch (Exception exception) {
            stringbuffer.append(getBytesAsString());
        }
        return stringbuffer.toString();
    }

    private void setValue(byte byte0, byte abyte0[], int i, int j) {
        id = byte0;
        setValue(abyte0, i, j);
    }

    private Attr(byte byte0, byte abyte0[], int i, int j) {
        this(byte0);
        setValue(abyte0, i, j);
    }

    private void setValue(byte abyte0[], int i, int j) {
        value = abyte0;
        offset = i;
        length = j;
    }

    private void setValue(byte byte0)
            throws ChatException {
        value = new byte[1];
        value[0] = byte0;
        length = 1;
    }

    private void setValue(int i)
            throws ChatException {
        try {
            ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
            (new DataOutputStream(bytearrayoutputstream)).writeInt(i);
            value = bytearrayoutputstream.toByteArray();
            length = value.length;
            intValue = new Integer(i);
        } catch (IOException ioexception) {
            throw new ChatException(ioexception.toString());
        }
    }

    private void setValue(String s)
            throws ChatException {
        try {
            ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
            (new DataOutputStream(bytearrayoutputstream)).writeUTF(s);
            value = bytearrayoutputstream.toByteArray();
            length = value.length;
            strValue = s;
        } catch (IOException ioexception) {
            throw new ChatException(ioexception.toString());
        }
    }
    public static final int BYTES = 0;
    public static final int STRING = 1;
    public static final int INTEGER = 2;
    public static final int IP = 3;
    public static final int SECS = 4;
    public static final int TIME = 5;
    public static final int COMMAND = 6;
    public static final int EVENT = 7;
    
    private byte id;
    private byte value[];
    private int offset;
    private int length;
    private String strValue;
    private Integer intValue;
    private static char hex[] = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'a', 'b', 'c', 'd', 'e', 'f'
    };
}
